home *** CD-ROM | disk | FTP | other *** search
- TITLE OBJREND - RENDERER SUPPORT MATH IN ASSEMBLER
-
- COMMENT $
-
- // 26/12/93 by Dave Stampe
- // All algorithms and code (c) 1993 by Dave Stampe
-
- /*
- This code is part of the REND386 project, created by Dave Stampe and
- Bernie Roehl.
-
- Copyright 1992, 1993, 1994 by Dave Stampe and Bernie Roehl.
-
- May be freely used to write software for release into the public domain;
- all commercial endeavours MUST contact BOTH Bernie Roehl and Dave Stampe
- for permission to incorporate any part of this software into their
- products! Usually there is no charge for under 50-100 items for
- low-cost or shareware, and terms are reasonable. Any royalties are used
- for development, so equipment is often acceptable payment.
-
- ATTRIBUTION: If you use any part of this source code or the libraries
- in your projects, you must give attribution to REND386, Dave Stampe,
- and Bernie Roehl in your documentation, source code, and at startup
- of your program. Let's keep the freeware ball rolling! No more
- code ripoffs please.
-
- CONTACTS: dstampe@psych.toronto.edu, broehl@sunee.uwaterloo.ca
- See the COPYRITE.H file for more information.
- */
-
- This file has object and poly depth-sorting code and object
- bounding sphere view-volume clipping routines. It also computes
- the screen extent of the object bounding sphere (roughly) and
- preclears object flags for rendering.
-
- Both quicksort and insertion sort are supplied, to optimally
- support poly counts from 2 to 2000.
-
-
-
- /* Contact: dstampe@sunee.waterloo.edu */
-
- $
-
- .MODEL large
- .386
-
- .DATA
-
- include 3dstruct.inc
- include viewdata.inc
-
- .CODE RENDERER
-
-
-
- ;/********* QUICKSORT OF OBJECT OR POLYS BY DEPTH *******/
-
- ; uses near ptrs for speed
- ; sorta in descending order
-
- ;/* m, n actually near ptrs into array */
- ;/* es is seg. of array throughout */
- ;/* keep array under 64K in size! */
-
- ;static void qsort_iter(int m, int n)
- ; NEAR for speed
-
-
- m equ [bp+6]
- n equ [bp+4]
-
- qsort_iter PROC NEAR
-
- push bp
- mov bp,sp
- mov si,m ; end of sort tree?
- cmp si,n
- jge end_of_sort
-
- mov di,n ; setup for pass
- add di,8
- mov eax,DWORD PTR es:[si].DS_depth
- gloop:
- fmax: ; find one less than current
- add si,8
- cmp DWORD PTR es:[si].DS_depth,eax
- jg fmax
- fmin: ; find one grater than current
- sub di,8
- cmp DWORD PTR es:[di].DS_depth,eax
- jl fmin
-
- cmp si,di ; swap or subdivide?
- jge nonswap
-
- mov ebx,DWORD PTR es:[si] ; just swap entries, try next
- mov edx,DWORD PTR es:[di]
- mov DWORD PTR es:[di],ebx
- mov DWORD PTR es:[si],edx
- mov ebx,DWORD PTR es:[si+4]
- mov edx,DWORD PTR es:[di+4]
- mov DWORD PTR es:[di+4],ebx
- mov DWORD PTR es:[si+4],edx
- jmp gloop
-
- nonswap: ; swap and subdivide
- mov si,m
- mov ebx,DWORD PTR es:[si]
- mov edx,DWORD PTR es:[di]
- mov DWORD PTR es:[di],ebx
- mov DWORD PTR es:[si],edx
- mov ebx,DWORD PTR es:[si+4]
- mov edx,DWORD PTR es:[di+4]
- mov DWORD PTR es:[di+4],ebx
- mov DWORD PTR es:[si+4],edx
-
- sub di,8 ; pivot - 1
- cmp si,di
- jge skip_qs1
- push si ; m argument
- push di ; n argument
- call near ptr qsort_iter
- pop di
- pop si
- skip_qs1:
- add di,16 ; pivot + 1
- cmp di,WORD PTR n
- jge end_of_sort
- push di ; m argument
- push WORD PTR n ; n argument
- call near ptr qsort_iter
- add sp,4
- end_of_sort:
- pop bp
- retn
-
- qsort_iter endp
-
-
-
- ; quicksort of poly/object array
- ;
- ; void qsort_dsort(DSORT far *first, DSORT far *last);
-
-
- first equ [bp+8] ; arguments
- last equ [bp+12]
-
- PUBLIC _qsort_dsort
-
- _qsort_dsort proc far
-
- .386
- push ebp
- mov ebp,esp
-
- push edx
- push ecx
- push esi
- push edi
-
- mov ax,WORD PTR first+2 ; args must be in same segment
- cmp ax,WORD PTR last+2
- jne no_sort
-
- les di,DWORD PTR first ; sanity check
- mov si,WORD PTR last
- cmp di,si
- jae no_sort
-
- push di ; start sort
- push si
- call near ptr qsort_iter
- add esp,4
-
- no_sort:
- pop edi
- pop esi
- pop ecx
- pop edx
-
- mov esp,ebp
- pop ebp
- ret
-
- _qsort_dsort endp
-
-
- ;/********* FAST SORT OF OBJECT OR POLYS BY DEPTH *******/
-
-
- ; insertion sort of poly/object array
- ; faster than quicksort if less than 16 items
- ; sorts in descending order
- ;
- ; void insertion_dsort(DSORT far *first, DSORT far *last);
-
-
- first equ DWORD PTR [bp+8] ; arguments
- last equ DWORD PTR [bp+12]
-
- PUBLIC _insertion_dsort
-
- _insertion_dsort proc far
-
- push ebp ; di is start/current pivot
- mov ebp,esp ; si is end marker
- ; bx is search pointer
- push edx ; eax is comparison
- push esi
- push edi
-
- mov ax,WORD PTR first+2 ; args must be in same segment
- cmp ax,WORD PTR last+2
- jne no_sort
-
- les di,DWORD PTR first
- mov si,WORD PTR last
-
- outer_loop: ; sanity/finished check
- cmp di,si
- jae end_sort
-
- mov bx,di ; search ptr
- mov eax,080000001h ; comparison value : init to big_neg
- mov dx,bx ; records biggest found
- find_loop:
- cmp eax,es:[bx].DS_depth ; biggest so far?
- jge dont_swap
-
- mov eax,es:[bx].DS_depth ; record
- mov dx,bx
- dont_swap:
- add bx,8 ; size DSORT ; next item
- cmp bx,si ; past last?
- jbe find_loop
-
- cmp dx,di ; no swap needed?
- je no_swap_req
-
- mov bx,dx
- mov eax,DWORD PTR es:[di] ; swap current with smallest
- mov edx,DWORD PTR es:[bx]
- mov DWORD PTR es:[bx],eax
- mov DWORD PTR es:[di],edx
- mov eax,DWORD PTR es:[bx+4]
- mov edx,DWORD PTR es:[di+4]
- mov DWORD PTR es:[di+4],eax
- mov DWORD PTR es:[bx+4],edx
-
- no_swap_req:
- add di,8 ; size DSORT
- jmp outer_loop
-
- end_sort:
- pop edi ; finished!
- pop esi
- pop edx
-
- mov esp,ebp
- pop ebp
- ret
-
- _insertion_dsort endp
-
-
-
-
- ;/************ OBJECT-CLIPPING BY VIEW VOLUME **************/
-
- ;#define OUT_OF_VIEW 0x8000000L // returned if we can't see object
-
- ;long obj_clip_by_volume(OBJECT *obj)
-
-
- obj equ DWORD PTR [bp+8] ; arguments
-
- center_z equ DWORD PTR [bp-4] ; locals
- center_z4 equ DWORD PTR [bp-8]
-
- tx equ DWORD PTR es:[bx].O_sphx ; bounding sphere center
- ty equ DWORD PTR es:[bx].O_sphy
- tz equ DWORD PTR es:[bx].O_sphz
- r equ DWORD PTR es:[bx].O_sphr ; bounding sphere radius
-
-
- PUBLIC _obj_clip_by_volume
-
- _obj_clip_by_volume proc far
-
- .386
- push ebp
- mov ebp,esp
- sub esp,12
-
- push esi
- push edi
- push ecx
-
- les bx,obj
-
- mov eax,_VS_fact7 ; convert center Z to camera coords
- mov edx,tx
- sub edx,_VS_iview_x
- imul edx
- mov esi,eax
- mov edi,edx
-
- mov eax,_VS_fact8
- mov edx,ty
- sub edx,_VS_iview_y
- imul edx
- add esi,eax
- adc edi,edx
-
- mov eax,_VS_fact9
- mov edx,tz
- sub edx,_VS_iview_z
- imul edx
- add esi,eax
- adc edi,edx
-
- shrd esi,edi,27 ;29-PRESCALEZ ; shift is prescaled
- mov center_z4,esi
- sar esi,2 ;PRESCALEZ ; now un-prescaled
- mov center_z,esi
-
- add esi,r
- cmp esi,_VS_hither
- jl outofview ; too close
-
- sub esi,r
- sub esi,r
- cmp esi,_VS_yon
- jg outofview ; too far
-
-
- mov eax,_VS_fact1 ; convert X coord to camera space
- mov edx,tx
- sub edx,_VS_iview_x
- imul edx
- mov esi,eax
- mov edi,edx
-
- mov eax,_VS_fact2
- mov edx,ty
- sub edx,_VS_iview_y
- imul edx
- add esi,eax
- adc edi,edx
-
- mov eax,_VS_fact3
- mov edx,tz
- sub edx,_VS_iview_z
- imul edx
- add esi,eax
- adc edi,edx
-
- shrd esi,edi,29 ; now camera x coord of center
-
- ; DO LEFT PLANE TEST
- mov eax,_VS_left_C ; multiply by slope
- neg eax
- imul center_z
- shrd eax,edx,29
- mov ecx,eax
- sub ecx,r
-
- mov eax,_VS_left_M ; second term
- imul esi
- shrd eax,edx,29
-
- cmp ecx,eax
- jg outofview ; too far left
-
- mov eax,_VS_right_C ; DO RIGHT PLANE TEST
- neg eax
- imul center_z
- shrd eax,edx,29
- mov ecx,eax
- sub ecx,r
-
- mov eax,_VS_right_M
- imul esi
- shrd eax,edx,29
-
- neg eax
- cmp ecx,eax
- jg outofview ; too far right
-
- mov eax,_VS_fact4 ; compute Y coord of center
- mov edx,tx
- sub edx,_VS_iview_x
- imul edx
- mov esi,eax
- mov edi,edx
-
- mov eax,_VS_fact5
- mov edx,ty
- sub edx,_VS_iview_y
- imul edx
- add esi,eax
- adc edi,edx
-
- mov eax,_VS_fact6
- mov edx,tz
- sub edx,_VS_iview_z
- imul edx
- add esi,eax
- adc edi,edx
-
- shrd esi,edi,29 ; y coord in camera space of center
-
- mov eax,_VS_bot_C ; BOTTOM PLANE CLIP
- neg eax
- imul center_z
- shrd eax,edx,29
- mov ecx,eax
- sub ecx,r
-
- mov eax,_VS_bot_M
- imul esi
- shrd eax,edx,29
-
- cmp ecx,eax
- jg outofview ; too far down
-
-
- mov eax,_VS_top_C ; TOP PLANE CLIP
- neg eax
- imul center_z
- shrd eax,edx,29
- mov ecx,eax
- sub ecx,r
-
- mov eax,_VS_top_M
- imul esi
- shrd eax,edx,29
-
- neg eax
- cmp ecx,eax ; too far up
- jg outofview
-
- mov eax,center_z4 ; return Z if OK
- jmp ret_32
-
- outofview:
- mov eax,OUT_OF_VIEW ; flag, none of sphere in view volume
- ret_32:
- shld edx,eax,16 ; return value in both EAX and DX:AX
-
- pop ecx
- pop edi
- pop esi
-
- mov esp,ebp
- pop ebp
- ret
-
- _obj_clip_by_volume endp
-
-
-
- ;/********* ESTIMATE SCREEN WIDTH FOR REP SELECT ***********/
-
- ; only use if object has passed preclip!
- ; returns -1 if error
- ;
- ; long compute_obj_screen_size(OBJECT *obj, long center_z);
-
- obj equ DWORD PTR [bp+8] ; arguments
- center_z equ DWORD PTR [bp+12]
-
- r equ DWORD PTR es:[bx].O_sphr ; bounding sphere radius
-
- PUBLIC _compute_obj_screen_size
-
- _compute_obj_screen_size proc far
-
- .386
- push ebp
- mov ebp,esp
-
- les bx,obj
- mov eax,r ; /* size = scale*radius/distance */
- imul DWORD PTR _VS_scx
- shrd eax,edx,8 ; /* range-extended <16.16> -> <32.0> */
- sar edx,8
- idiv DWORD PTR center_z
- sar eax,6 ; /* 2x true size so it's diameter */
-
- shld edx,eax,16 ; result in eax AND dx:ax
-
- mov esp,ebp
- pop ebp
- ret
-
- _compute_obj_screen_size endp
-
-
- ;/********* CLEAR OBJECT FLAGS FOR RENDERING ***********/
-
- ; a representation must be current!
- ;
- ; void prerender_clear_object(OBJECT *obj);
-
- obj equ DWORD PTR [bp+8] ; arguments
-
-
- PUBLIC _prerender_clear_object
-
- _prerender_clear_object proc far
-
- .386
- push ebp
- mov ebp,esp
-
- les bx,obj
- les bx,es:[bx].O_currep ; current object representation
- mov ax,es:[bx].R_nverts
- les bx,es:[bx].R_verts
- clear_loop:
- mov DWORD PTR es:[bx].V_nvptr,0
- mov WORD PTR es:[bx].V_zxflag,0 ; clears outcode and flags
- add bx,SIZE VERTEX
- dec ax
- jne clear_loop
-
- mov esp,ebp
- pop ebp
- ret
-
- _prerender_clear_object endp
-
-
-
- end
-
-
-
-
-
-